const express = require('express');
const multer = require('multer');
const fs = require('fs');
const path = require('path');
const qrcode = require('qrcode');
const { networkInterfaces } = require('os');

// 初始化Express应用
const app = express();
const PORT = 8000;
const UPLOAD_DIR = path.join(__dirname, 'uploads');

// 确保上传目录存在
if (!fs.existsSync(UPLOAD_DIR)) {
  fs.mkdirSync(UPLOAD_DIR, { recursive: true });
}

// 生成唯一文件名（处理重复上传）
function getUniqueFilename(directory, filename) {
  const ext = path.extname(filename);
  const base = path.basename(filename, ext);
  let counter = 1;
  let uniqueName = filename;
  
  while (fs.existsSync(path.join(directory, uniqueName))) {
    uniqueName = `${base}_${counter}${ext}`;
    counter++;
  }
  
  return uniqueName;
}

// 配置multer用于文件上传
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, UPLOAD_DIR);
  },
  filename: function (req, file, cb) {
    // 处理中文文件名并生成唯一名称
    const originalName = Buffer.from(file.originalname, 'latin1').toString('utf8');
    const uniqueName = getUniqueFilename(UPLOAD_DIR, originalName);
    cb(null, uniqueName);
  }
});

// 只允许图片文件
const fileFilter = (req, file, cb) => {
  if (file.mimetype.startsWith('image/')) {
    cb(null, true);
  } else {
    cb(new Error('只允许上传图片文件！'), false);
  }
};

const upload = multer({ storage: storage, fileFilter: fileFilter });

// 获取本地IP地址
function getLocalIP() {
  const nets = networkInterfaces();
  for (const name of Object.keys(nets)) {
    for (const net of nets[name]) {
      // 跳过IPv6和本地地址
      if (net.family === 'IPv4' && !net.internal) {
        return net.address;
      }
    }
  }
  return '127.0.0.1';
}

// 生成二维码
async function generateQRCode(data) {
  try {
    return await qrcode.toDataURL(data);
  } catch (err) {
    console.error('生成二维码失败:', err);
    return null;
  }
}

// 获取已上传的图片列表
function getImageList() {
  try {
    const files = fs.readdirSync(UPLOAD_DIR);
    return files.filter(file => {
      const ext = path.extname(file).toLowerCase();
      return ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp'].includes(ext);
    });
  } catch (err) {
    console.error('读取图片列表失败:', err);
    return [];
  }
}

// 主页路由
app.get('/', async (req, res) => {
  const localIP = getLocalIP();
  const serverUrl = `http://${localIP}:${PORT}`;
  const qrCodeDataUrl = await generateQRCode(serverUrl);
  const imageList = getImageList();

  // 生成图片网格HTML
  let imageGrid = '';
  imageList.forEach(filename => {
    // 对中文文件名进行URL编码
    const encodedFilename = encodeURIComponent(filename);
    imageGrid += `
      <div class="image-item">
        <a href="/uploads/${encodedFilename}" target="_blank">
          <img src="/uploads/${encodedFilename}" class="image-preview">
        </a>
        <p class="image-name">${filename}</p>
      </div>
    `;
  });

  // 构建HTML页面
  const html = `
  <!DOCTYPE html>
  <html>
  <head>
      <meta charset="UTF-8">
      <title>图片传输</title>
      <style>
          body { font-family: Arial, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; }
          h1 { color: #333; }
          .qrcode-section { margin: 20px 0; padding: 20px; background-color: #f8f9fa; border-radius: 8px; }
          .qrcode-container { display: inline-block; padding: 15px; background: white; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
          .upload-form { margin: 20px 0; padding: 20px; background-color: #f5f5f5; border-radius: 8px; }
          .file-input { padding: 10px 20px; font-size: 16px; margin-right: 10px; }
          .submit-btn { padding: 10px 20px; font-size: 16px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; }
          .submit-btn:hover { background-color: #45a049; }
          .image-grid { display: grid; grid-template-columns: repeat(auto-fill, 200px); gap: 10px; margin-top: 20px; }
          .image-item { text-align: center; padding: 10px; background-color: #f9f9f9; border-radius: 4px; }
          .image-preview { max-width: 100%; max-height: 150px; object-fit: cover; border: 1px solid #ddd; border-radius: 4px; }
          .image-name { margin: 5px 0; word-break: break-all; font-size: 14px; }
          .error-message { color: #dc3545; margin: 10px 0; }
      </style>
  </head>
  <body>
      <h1>图片传输服务器</h1>
      
      <div class="qrcode-section">
          <h3>手机扫码访问</h3>
          <div class="qrcode-container">
              ${qrCodeDataUrl ? `<img src="${qrCodeDataUrl}" alt="访问二维码">` : '<p>无法生成二维码</p>'}
          </div>
          <p style="margin-top: 10px;">服务器地址: ${serverUrl}</p>
      </div>
      
      <div class="upload-form">
          <form method="POST" enctype="multipart/form-data" action="/upload">
              <input type="file" name="images" accept="image/*" multiple class="file-input">
              <input type="submit" value="上传图片" class="submit-btn">
          </form>
          ${req.query.error ? `<p class="error-message">${req.query.error}</p>` : ''}
      </div>
      
      <hr>
      <h3>已上传图片</h3>
      <div class="image-grid">
          ${imageGrid || '<p>暂无上传的图片</p>'}
      </div>
  </body>
  </html>
  `;

  res.send(html);
});

// 处理文件上传
app.post('/upload', upload.array('images'), (req, res) => {
  if (!req.files || req.files.length === 0) {
    return res.redirect('/?error=请选择要上传的图片');
  }
  res.redirect('/');
});

// 提供上传的图片访问，支持中文文件名
app.get('/uploads/:filename', (req, res) => {
  try {
    // 解码URL中的文件名
    const filename = decodeURIComponent(req.params.filename);
    const filepath = path.join(UPLOAD_DIR, filename);
    
    // 检查文件是否存在
    if (fs.existsSync(filepath) && fs.lstatSync(filepath).isFile()) {
      res.sendFile(filepath);
    } else {
      res.status(404).send('图片不存在');
    }
  } catch (err) {
    console.error('访问图片出错:', err);
    res.status(500).send('访问图片时出错');
  }
});

// 错误处理中间件
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.redirect(`/?error=${encodeURIComponent(err.message)}`);
});

// 启动服务器
app.listen(PORT, () => {
  const localIP = getLocalIP();
  console.log(`图片服务器已启动！`);
  console.log(`存储目录：${UPLOAD_DIR}`);
  console.log(`本地访问：http://localhost:${PORT}`);
  console.log(`局域网访问：http://${localIP}:${PORT}`);
});
